package com.lam.common.components.dict;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lam.common.components.dict.constant.DictConstant;
import com.lam.common.components.dict.model.DictDefaultModel;
import com.lam.common.components.dict.model.DictModel;
import com.lam.common.components.dict.model.TableDictInfo;
import com.lam.common.components.dict.service.DictService;
import com.lam.common.components.dict.service.TableDictConfigService;
import com.lam.common.components.redis.RedisUtil;
import com.lam.common.utils.CollectionUtil;
import com.lam.common.utils.SpringUtils;
import com.lam.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 字典工具类
 * 
 * @author lam
 */
public class DictCacheUtils {
	
	private static final Logger logger = LoggerFactory.getLogger(DictCacheUtils.class);
	
	/** 分隔符 */
	public static final String SEPARATOR = ",";
	
	public static DictService getDictService() {
		return SpringUtils.getBean(DictService.class);
	}
	
	// ================================= Dict操作开始  =====================================================
	
	/**
	 * 获取字典缓存key
	 * 
	 * @param dictCode 字典编码
	 */
	public static String getDictCacheKey(String dictCode) {
		return DictConstant.SYS_DICT_KEY + dictCode;
	}

	/**
	 * 删除字典缓存
	 * @param dictCode
	 */
	public static void delDictCache(String dictCode) {
		RedisUtil.del(getDictCacheKey(dictCode));
	}
	
	/**
	 * 清空字典缓存
	 */
	public static void clearDictCache() {
		RedisUtil.removeAll(DictConstant.SYS_DICT_KEY);
	}

	/**
	 * 获取字典缓存
	 * 
	 * @param dictCode 参数键
	 */
	public static List<DictModel> getDictCache(String dictCode) {
		if(StringUtils.isBlank(dictCode)) {
			return Collections.emptyList();
		}
		String redisKey = getDictCacheKey(dictCode);
		Object cacheObj = RedisUtil.get(redisKey);
		if (cacheObj != null) {
			return CollectionUtil.cast(cacheObj);
		}
		
		List<DictModel> list = convertDictModel(getDictService().selectDictItems(dictCode));
		RedisUtil.set(redisKey, list, DictConstant.SYS_DICT_EXPIRE);
		return list;
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param dictCode 参数键
	 * @return Map键值对 value为字典值，text为字典标签
	 */
	public static Map<String, String> getDictMap(String dictCode) {
		return getDictMap(dictCode, false);
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param dictCode 参数键
	 * @param reverse 是否反转
	 * @return Map键值对，reverse为false，则value为字典值，text为字典标签，reverse为true，则为text字典值，value为字典标签
	 */
	public static Map<String, String> getDictMap(String dictCode, boolean reverse) {
		return convertDict2Map(getDictCache(dictCode), reverse);
	}
	// ================================= Dict操作结束  =====================================================
	
	public static Map<String, String> convertDict2Map(List<DictModel> list, boolean reverse){
		if (CollectionUtil.isEmpty(list)) {
			return Collections.emptyMap();
		}
		
		Map<String, String> dictMap = new HashMap<>();
		if(reverse){
			for (DictModel dictModel : list) {
				dictMap.put(dictModel.getText(), dictModel.getValue());
			}
		}else{
			for (DictModel dictModel : list) {
				dictMap.put(dictModel.getValue(), dictModel.getText());
			}
		}
		return dictMap;
	}
	
	// ================================= TableDict操作开始  =====================================================
	
	/**
	 * 删除自定义table字典缓存
	 * @param dictCode
	 */
	public static void delTableDictCache(TableDictInfo tableDictInfo) {
		RedisUtil.del(getTableDictCacheKey(tableDictInfo));
	}
	
	/**
	 * 根据表名 删除自定义table字典缓存，包含该表名的都会被删除
	 * @param tableName 
	 */
	public static void delTableDictCache(String tableName) {
		
		RedisUtil.removeAll(DictConstant.SYS_TABLE_DICT_PREFIX + tableName);
	}
	
	/**
	 * 清空自定义table字典缓存
	 */
	public static void clearTableDictCache() {
		RedisUtil.removeAll(DictConstant.SYS_TABLE_DICT_PREFIX);
	}
	
	private static TableDictConfigService getTableDictConfigService() {
		TableDictConfigService service = SpringUtils.getBean(TableDictConfigService.class);
		if(service == null) {
			logger.debug("未开启Table字典配置！");
		}
		return service;
	}
	
	public static List<String> getAllConfigTableName() {
		
		TableDictConfigService service = getTableDictConfigService();
		return service == null?null:service.selectAllTableName();
	}
	
	public static TableDictInfo getTableDictConfig(String dictCode) {
		
		TableDictConfigService service = getTableDictConfigService();
		return service == null?null:service.selectTableDictConfig(dictCode);
	}
	
	/**
	 * 获取自定义表类型的字典缓存
	 * 
	 * @param tableMappingName 表映射名称
	 * @return
	 */
	public static List<DictModel> getTableDictCache(String dictCode) {
		
		return DictCacheUtils.getTableDictCache(getTableDictConfig(dictCode));
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param dictCode 自定义表字典名
	 * @return Map键值对 value为字典值，text为字典标签
	 */
	public static Map<String, String> getTableDictMap(String dictCode) {
		return getTableDictMap(dictCode, false);
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param dictCode 自定义表字典名
	 * @param reverse 是否反转
	 * @return Map键值对，reverse为false，则value为字典值，text为字典标签，reverse为true，则为text字典值，value为字典标签
	 */
	public static Map<String, String> getTableDictMap(String dictCode, boolean reverse) {
		return convertDict2Map(getTableDictCache(dictCode), reverse);
	}
	
	/**
	 * 获取自定义表类型的字典缓存
	 * 
	 * @param tableDictInfo 
	 */
	public static List<DictModel> getTableDictCache(TableDictInfo tableDictInfo) {
		if(tableDictInfo == null || tableDictInfo.isAnyBlank()) {
			return Collections.emptyList();
		}
		
		String redisKey = getTableDictCacheKey(tableDictInfo);
		Object cacheObj = RedisUtil.get(redisKey);
		if (cacheObj != null) {
			return CollectionUtil.cast(cacheObj);
		}
		
		List<DictModel> list = convertDictModel(getDictService().selectTableDictItems(tableDictInfo));
		RedisUtil.set(redisKey, list, tableDictInfo.getCacheExpire()>1?tableDictInfo.getCacheExpire():DictConstant.SYS_DICT_EXPIRE);
		return list;
	}
	
	/**
	 * 获取自定义表类型字典缓存key
	 */
	private static String getTableDictCacheKey(TableDictInfo tableDictInfo) {
		return String.format(DictConstant.SYS_TABLE_DICT_KEY, tableDictInfo.getTableName(), tableDictInfo.getValueField(), 
				tableDictInfo.getTextField(), tableDictInfo.getExeConditionSql());
	}
	
	private static List<DictModel> convertDictModel(List<DictModel> list){
		List<DictModel> newList = new ArrayList<>();
		if(CollectionUtil.isEmpty(list)) {
			return newList;
		}
		for (DictModel dictModel : list) {
			newList.add(new DictDefaultModel(dictModel));
		}
		return newList;
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param tableDictInfo 
	 * @return Map键值对 value为字典值，text为字典标签
	 */
	public static Map<String, String> getTableDictMap(TableDictInfo tableDictInfo) {
		return getTableDictMap(tableDictInfo, false);
	}
	
	/**
	 * 获取字典缓存
	 * 
	 * @param tableDictInfo 
	 * @param reverse 是否反转
	 * @return Map键值对，reverse为false，则value为字典值，text为字典标签，reverse为true，则为text字典值，value为字典标签
	 */
	public static Map<String, String> getTableDictMap(TableDictInfo tableDictInfo, boolean reverse) {
		return convertDict2Map(getTableDictCache(tableDictInfo), reverse);
	}
	
	// ================================= TableDict操作结束  =====================================================
	
	public static String convertDictKey(Map<String, String> dictMap, String key) {
		return convertDictKey(dictMap, key, SEPARATOR);
	}
	
	public static String convertDictKey(Map<String, String> dictMap, String key, String separator) {
		
		if(CollectionUtil.isEmpty(dictMap) || StringUtils.isBlank(key)){
			return StringUtils.EMPTY;
		}
		if(StringUtils.isBlank(separator)){
			separator = SEPARATOR;
		}
		
		String v;
		if (StringUtils.contains(key, separator)) {
			StringBuilder sb = new StringBuilder();
			for (String k : key.split(separator)) {
				v = dictMap.get(k);
				sb.append(StringUtils.isEmpty(v) ? StringUtils.EMPTY : v).append(separator);
			}
			return StringUtils.stripEnd(sb.toString(), separator);
		} 
		
		v = dictMap.get(key);
		return StringUtils.isEmpty(v)?StringUtils.EMPTY:v;
	}

}
